﻿using System.Windows;
using System.Windows.Interactivity;

namespace Black.Minecraft.Editor.Behaviors
{
    /// <summary>
    /// Classe de défintion du behavior pour gérer les états du VisualStateManager
    /// </summary>
    public class VisualStateBehavior : Behavior<FrameworkElement>
    {
        #region Propriétés de dépendances

        public static readonly DependencyProperty PlayStoryboardProperty = DependencyProperty.Register("PlayStoryboard", typeof(bool), typeof(VisualStateBehavior), new UIPropertyMetadata(true));
        public static readonly DependencyProperty GoToElementStateProperty = DependencyProperty.Register("GoToElementState", typeof(string), typeof(VisualStateBehavior), new UIPropertyMetadata(null, VisualStateBehavior.OnGoToElementStateChanged));
        public static readonly DependencyProperty GoToStateProperty = DependencyProperty.Register("GoToState", typeof(string), typeof(VisualStateBehavior), new UIPropertyMetadata(null, VisualStateBehavior.OnGoToStateChanged));

        #endregion

        #region Propriétés


        /// <summary>
        /// Obtient ou défini la valeur de la propriété de dépendance PlayStoryboard
        /// </summary>
        public bool PlayStoryboard
        {
            get
            {
                return ((bool)this.GetValue(VisualStateBehavior.PlayStoryboardProperty));
            }
            set
            {
                this.SetValue(VisualStateBehavior.PlayStoryboardProperty, value);
            }
        }

        /// <summary>
        /// Obtient ou défini la valeur de la propriété de dépendance GotToElementState
        /// </summary>
        public string GoToElementState
        {
            get
            {
                return ((string)this.GetValue(VisualStateBehavior.GoToElementStateProperty));
            }
            set
            {
                this.SetValue(VisualStateBehavior.GoToElementStateProperty, value);
            }
        }

        /// <summary>
        /// Obtient ou défini la valeur de la propriété de dépendance GotToState
        /// </summary>
        public string GoToState
        {
            get
            {
                return ((string)this.GetValue(VisualStateBehavior.GoToStateProperty));
            }
            set
            {
                this.SetValue(VisualStateBehavior.GoToStateProperty, value);
            }
        }

        #endregion

        #region Fonctions protégées

        /// <summary>
        /// Se produit sur l'attachement de l'objet
        /// </summary>
        protected override void OnAttached()
        {
            base.OnAttached();

            // L'événement étant levé après l'affectation, on le relance

            if (!string.IsNullOrWhiteSpace(this.GoToElementState))
                this.OnGoToElementStateChanged(null, this.GoToElementState);

            if (!string.IsNullOrWhiteSpace(this.GoToState))
                this.OnGoToStateChanged(null, this.GoToState);
        }

        /// <summary>
        /// Se produit sur un changement de la propriété de dépendance GoToElementState
        /// </summary>
        /// <param name="oldValue">Ancienne valeur</param>
        /// <param name="newValue">Nouvelle valeur</param>
        protected virtual void OnGoToElementStateChanged(string oldValue, string newValue)
        {
            // Passage de la valeur

            if (this.AssociatedObject != null && !string.IsNullOrWhiteSpace(newValue))
                VisualStateManager.GoToElementState(this.AssociatedObject, newValue, this.PlayStoryboard);
        }

        /// <summary>
        /// Se produit sur un changement de la propriété de dépendance GoToState
        /// </summary>
        /// <param name="oldValue">Ancienne valeur</param>
        /// <param name="newValue">Nouvelle valeur</param>
        protected virtual void OnGoToStateChanged(string oldValue, string newValue)
        {
            // Passage de la valeur

            if (this.AssociatedObject != null && !string.IsNullOrWhiteSpace(newValue))
                VisualStateManager.GoToState(this.AssociatedObject, newValue, this.PlayStoryboard);
        }

        #endregion

        #region Fonctions statiques

        /// <summary>
        /// Se produit sur le changement de la propriété GoToElementState
        /// </summary>
        /// <param name="sender">Source de l'appel</param>
        /// <param name="e">Argument de l'appel</param>
        private static void OnGoToElementStateChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            (sender as VisualStateBehavior).OnGoToElementStateChanged((string)e.OldValue, (string)e.NewValue);
        }

        /// <summary>
        /// Se produit sur le changement de la propriété GoToState
        /// </summary>
        /// <param name="sender">Source de l'appel</param>
        /// <param name="e">Argument de l'appel</param>
        private static void OnGoToStateChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            (sender as VisualStateBehavior).OnGoToStateChanged((string)e.OldValue, (string)e.NewValue);
        }

        #endregion
    }
}
